import {Module} from "../framework.js"
import Collection from '../collection.js';
import * as WidgetEvent from './widget-event.js'
import {WIDGET_DISPLAY_MODE, WIDGET_TYPE} from './widget-const.js';
import {Widget, PlaceholderWidget} from "./widget.js"
import D from '../delegator.js'
import * as UI from "../ui.js"

/**
 * 1) hold all widget instances;
 * 2) handle widget HTMLElement relative logics;
 */
export default class WidgetGroup extends Module {
    constructor(disp) {
        super(disp);
        this._ui = UI.UIWidgetGroup();
        this._widgetCollection = Collection('WID');
        this._lastFocusedWidget = undefined;
        //this._placeholderWidget = new PlaceholderWidget();
        //
        //
        this._widgetCreateFn = WID => {
            console.log('create:',WID);
            let _offset = this._widgetCollection.length;
            const _widget = this._widgetCollection.GetByKey(WID);
            if(_widget) {
                _offset = this._widgetCollection.IndexOf(_widget);
            }
            this.Dispatch(WidgetEvent.CreateBtnClickedEvent(_widget, _offset));
        }
        this._widgetToggleFn = WID => {
            console.log('toggle:', WID);
            const _widget = this._widgetCollection.GetByKey(WID);
            switch(_widget.mode) {
                case WIDGET_DISPLAY_MODE.VIEW:
                    this.Dispatch(WidgetEvent.ChangedToEditEvent(_widget));
                    _widget.ShowEditPane();
                    this.FocusWidget(_widget);
                    break;
                case WIDGET_DISPLAY_MODE.EDIT:
                    this.ChangeWidgetToViewMode(_widget);
                    break;
            }
        }
        this._contentClickFn = WID => {
            console.log('content clicked:',WID);
            const _widget = this._widgetCollection.GetByKey(WID);
            if(_widget.mode === WIDGET_DISPLAY_MODE.VIEW) return;
            this.FocusWidget(_widget);
        }
        this._contentChangedFn = _ => {
            if(this._lastFocusedWidget)
                this._lastFocusedWidget.SetDirty();
                this.Dispatch(WidgetEvent.ContentChangedEvent(this._lastFocusedWidget));
        };

    }

    ChangeWidgetToViewMode(widget) {
        if(!widget) widget = this._lastFocusedWidget;
        const _dirty = widget.dirty;
        if(_dirty){
            widget.Upload();
            widget.Render();
            widget.SetClean();
            this.Dispatch(WidgetEvent.DirtyContentChangedToViewEvent(widget));
        }
        widget.ShowViewPane();
        this.Dispatch(WidgetEvent.ChangedToViewEvent(widget, _dirty));
        if(widget === this._lastFocusedWidget) {
            this._lastFocusedWidget = null;
        }
    }

    ScrollToWidget(WID) {
        const _widget = this._widgetCollection.GetByKey(WID);
        _widget.Aim();
    }

    FocusWidget(widget) {
        if(this._lastFocusedWidget === widget) return;
        if(this._lastFocusedWidget) {
            this._lastFocusedWidget.Blur();
            this.Dispatch(WidgetEvent.ChangedToEditBlurEvent(this._lastFocusedWidget));
            this._lastFocusedWidget = null;
        }
        if(widget) {
            this._lastFocusedWidget = widget;
            widget.Focus();
            this.Dispatch(WidgetEvent.ChangedToEditFocusEvent(widget));
        }
    }

    MoveHigher(WID) {
        const _widget = this._widgetCollection.GetByKey(WID);
        if (_widget) {
            const _idx = this._widgetCollection.MoveUp(_widget);
            if (_idx >= 0) {
                this._ui.InsertWidgetElement(_widget.ui, _idx);
            }
            return _idx;
        }
        return -1;
    }
    MoveLower(WID) {
        const _widget = this._widgetCollection.GetByKey(WID);
        if(_widget) {
            let _idx = this._widgetCollection.MoveDown(_widget);
            if(_idx >= 0) {
                this._ui.InsertWidgetElement(_widget.ui, _idx);
            }
            return _idx;
        } return -1;
    }

    Insert(widget, pivotWidget){
        if (pivotWidget) {
            this._widgetCollection.InsertBefore(widget,pivotWidget);
        } else {
            this._widgetCollection.Insert(widget);
        }
        const _idx= this._widgetCollection.IndexOf(widget);
        this._ui.InsertWidgetElement(widget.ui, _idx);
        return _idx;
    }

    Insert(widget, offset){
        const pivotWidget = this._widgetCollection.GetByIndex(offset) ?? this._placeholderWidget;
        if (pivotWidget) {
            this._widgetCollection.InsertBefore(widget,pivotWidget);
        } else {
            this._widgetCollection.Insert(widget);
        }
        const _idx= this._widgetCollection.IndexOf(widget);
        this._ui.InsertWidgetElement(widget.ui, _idx);
        return _idx;
    }

    Clear() {
        this._ui.RemoveAll();
        this._widgetCollection.ForEach((_w) => {
            _w.Destroy();
            return false;
        }, this);
        this._widgetCollection.Clear();

        //this.Insert(this._placeholderWidget);
        this._lastFocusedWidget = undefined;
    }

    CreateWidget(widgetContent, mode) {
        const _w = new Widget(widgetContent, mode, this._contentChangedFn);
        _w.ui.SetAction(this._widgetCreateFn, this._widgetToggleFn, this._contentClickFn);
        return _w;
    }

    DeleteWidget(WID) {
        const _widget = this._widgetCollection.GetByKey(WID);
        if (this._widgetCollection.Remove(_widget)) {
            _widget.Destroy();
            if (_widget === this._lastFocusedWidget) {
                this._lastFocusedWidget = null;
            }
            return true;
        }
        return false;
    }

    GetWidget(WID) {
        return this._widgetCollection.GetByKey(WID);
    }

    get count() {
        return this._widgetCollection.length;
    }
}

